package com.szakul.pdf.model;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.szakul.pdf.viewer.dao.beans.Leaf;
import com.szakul.pdf.viewer.dao.beans.Node;
import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.terminal.StreamResource;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.Tree;

@Component
public class ViewModel {

	private static final Logger LOGGER = Logger.getLogger(ViewModel.class);
	
	private Application application;

	private PdfModel pdfModel;

	private IndexedContainer pdf;

	private int currentPage;
	
	private Zoom currentZoom;

	private String currentFileName;
	
	private String currentSearchText;

	private TreeModelDao treeModelDao;
	

	public ViewModel(Application application, TreeModelDao treeModelDao) {
		super();
		this.application = application;
		this.treeModelDao = treeModelDao;

	}
	
	public ViewModel() {
		
	}

	public List<Integer> getSearchPages(String searchWorld) {
		
		List<Integer> result = new ArrayList<Integer>();
		
		if(pdfModel != null) {
			try {
				return pdfModel.getSearchPages(searchWorld);
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
		
		return result;
	}
	
	
	public Page goPageSearch(int page, String text) {
		Page toReturn = new Page();
		
		currentSearchText = text;
		
		pdf = new IndexedContainer();

		pdf.addContainerProperty(currentFileName, Embedded.class, null);

		Object id = pdf.addItem();

		Embedded image = getEmbeddedSearchPage(pdfModel, page, text);
		
		pdf.getContainerProperty(id, currentFileName).setValue(image);

		toReturn.setImage(image);
		toReturn.setIndexedContainer(pdf);
		
		return toReturn;
	}
	
	public Page goPage(int page) {
		
		Page toReturn = new Page();
		
		pdf = new IndexedContainer();

		pdf.addContainerProperty(currentFileName, Embedded.class, null);

		Object id = pdf.addItem();

		Embedded image = getEmbeddedPage(pdfModel, Zoom.ZOOM_100, page);
		pdf.getContainerProperty(id, currentFileName).setValue(image);

		toReturn.setImage(image);
		toReturn.setIndexedContainer(pdf);
		
		return toReturn;
	}
	
	public Page zoomPage(Zoom zoom) {

		Page toReturn = new Page();
		
		pdf = new IndexedContainer();

		pdf.addContainerProperty(currentFileName, Embedded.class, null);

		Object id = pdf.addItem();

		Embedded image = getEmbeddedPage(pdfModel, zoom, -1);

		pdf.getContainerProperty(id, currentFileName).setValue(image);

		toReturn.setImage(image);
		toReturn.setIndexedContainer(pdf);
		
		return toReturn;
	}

	public Page createPage(String fileName, Zoom zoom, int page) {

		currentFileName = fileName;
		currentPage = page;

		Page toReturn = new Page();

		pdfModel = new PdfModel(fileName);
		pdf = new IndexedContainer();

		pdf.addContainerProperty(fileName, Embedded.class, null);

		Object id = pdf.addItem();

		Embedded image = getEmbeddedPage(pdfModel, zoom, page);
		image.setReadOnly(true);

		pdf.getContainerProperty(id, fileName).setValue(image);

		toReturn.setImage(image);
		toReturn.setIndexedContainer(pdf);
		
		return toReturn;
	}

	/**
	 * @return the currentPage
	 */
	public int getCurrentPage() {
		return currentPage;
	}

	public int getAllPages() {

		if (pdfModel != null) {

			return pdfModel.getNumperOfPages();
		}

		return 0;
	}

	private Embedded getEmbeddedSearchPage(PdfModel pdfModel,int page, String text) {
		StreamResource imageresource = null;
		try {

			String fName = page + UUID.randomUUID().toString() + ".png";

			imageresource = new StreamResource(pdfModel.getPage(page, text),
						fName, application);

			Embedded statusImage = new Embedded(fName, imageresource);
			

			return statusImage;
		} catch (IOException e) {

			e.printStackTrace();
		}

		return null;
	}
	
	
	
	
	private Embedded getEmbeddedPage(PdfModel pdfModel, Zoom zoom, int page) {
		StreamResource imageresource = null;
		try {

			String fName = page + UUID.randomUUID().toString() + ".png";

			if(page == -1) {
				imageresource = new StreamResource(pdfModel.zoomCurrentPage(zoom),
						fName, application);
			}
			else {
				imageresource = new StreamResource(pdfModel.getPage(page),
						fName, application);
			}

			Embedded statusImage = new Embedded(fName, imageresource);

			LOGGER.debug("Set image size W: " + pdfModel.getWidth() + " H: "+ pdfModel.getHeight());
			
			statusImage.setWidth(pdfModel.getWidth() + "px");
			statusImage.setHeight(pdfModel.getHeight() + "px");	

			
			
			return statusImage;
		} catch (IOException e) {

			e.printStackTrace();
		}

		return null;
	}

	public void setTree(Tree tree) {

        Object rootItemId = tree.addItem();
        tree.setChildrenAllowed(rootItemId, true);
        tree.getContainerProperty(rootItemId, TreePageModel.TREE_PAGE_MODEL).setValue("Repozytorium");
        tree.getContainerProperty(rootItemId, TreePageModel.CAPTION).setValue("Repozytorium");
		
		
		List<Node> nodes = treeModelDao.getAllNodes();
		
		for(Node node: nodes) {
			
            Object parentItemId = tree.addItem();
            tree.setParent(parentItemId, rootItemId);
            tree.setChildrenAllowed(parentItemId, true);
            tree.getContainerProperty(parentItemId, TreePageModel.TREE_PAGE_MODEL).setValue(node);
            tree.getContainerProperty(parentItemId, TreePageModel.CAPTION).setValue(node.getName());

			LOGGER.debug("node: " + node.getName());
			List<Leaf> leafs = treeModelDao.getNodeLeafs(node);
			for(Leaf leaf: leafs) {
				LOGGER.debug("  -leaf: " + leaf.getName() + " belongs to " + node.getName());
				
				Object itemId = tree.addItem();
				tree.setParent(itemId, parentItemId);
				tree.setChildrenAllowed(itemId, false);
				Item item = tree.getItem(itemId);
	            item.getItemProperty(TreePageModel.CAPTION).setValue(leaf.getName());
	            item.getItemProperty(TreePageModel.TREE_PAGE_MODEL).setValue(leaf);

			}
			
		}
		
		tree.expandItemsRecursively(rootItemId);
		
		
		
		/*
		List<File> result = LuceneRepository.getAllFiles();

		System.out.println("Get all files: ");

		for (File file : result) {
			System.out.println("name " + file.getName());

			//tree.addItem(file.getName());
		}
		*/
	}

	public Application getApplication() {
		return application;
	}

	/**
	 * @return the currentFileName
	 */
	public String getCurrentFileName() {
		return currentFileName;
	}

	/**
	 * @return the currentSearchText
	 */
	public String getCurrentSearchText() {
		return currentSearchText;
	}
	
	public void updateLeaf(final Leaf leaf) {
		treeModelDao.updateLeaf(leaf);
	}

	public void updateNode(final Node node) {
		treeModelDao.updateNode(node);
	}
	
	public void createNode(Node node) {
		treeModelDao.createNode(node);
	}
	
	public void createLeaf(Leaf leaf) {
		treeModelDao.createLeaf(leaf);
	}
	
	public void createLeaf(final Leaf leaf, final Node node) {
		leaf.setNode(node);
		treeModelDao.createLeaf(leaf);
		node.getLeaf().add(leaf);
		treeModelDao.updateNode(node);
		
	}
	
	
	public void deleteNode(final Node node) {
		treeModelDao.deleteNode(node);
	}
	
	public void deleteLeaf(final Leaf leaf) {
		treeModelDao.deleteLeaf(leaf);
	}
	
}
